﻿

using Admin.NET.Core.Btms;
using AngleSharp.Dom;
using Furion.DatabaseAccessor;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Text;
using Org.BouncyCastle.Tsp;
using Yitter.IdGenerator;

namespace Admin.NET.Application.Service;
public class TraKuaiSuFaXueService : IDynamicApiController
{
    private readonly BillNoManager _billNoManager;
    private readonly SqlSugarRepository<TraShenQing> _traShenQingRep;
    private readonly SqlSugarRepository<TraShenQingHuanZhe> _taShenQingHuanZheRep;
    private readonly SqlSugarRepository<TraShenQingYongXue> _traShenQingYongXueRep;

    private readonly SqlSugarRepository<TraFuHe> _traShenQingFuHeRep;


    private readonly SqlSugarRepository<TraPeiXue> _traShenQingPeiXueZhuBiaoRep;
    private readonly SqlSugarRepository<TraPeiXueMingXi> _traShenQingPeiXueZiBiaoRep;
    private readonly SqlSugarRepository<TraFaXue> _traShenQingFaXueZhuBiaoRep;
    private readonly SqlSugarRepository<TraFaXueMingXi> _traShenQingFaXueMingXiRep;

    public readonly  SqlSugarRepository<TraShenQingJianYan> _traShenQingJianYanRep;


    private readonly SqlSugarRepository<InvKuCun> _invKuCunRep;

    public TraKuaiSuFaXueService(BillNoManager billNoManager, SqlSugarRepository<TraShenQing> traShenQingRep, SqlSugarRepository<TraShenQingHuanZhe> taShenQingHuanZheRep,
        SqlSugarRepository<TraShenQingYongXue> traShenQingYongXueRep, SqlSugarRepository<TraFuHe> traShenQingFuHeRep,
        SqlSugarRepository<TraPeiXue> traShenQingPeiXueZhuBiaoRep, SqlSugarRepository<TraPeiXueMingXi> traShenQingPeiXueZiBiaoRep,
        SqlSugarRepository<TraFaXue> traShenQingFaXueZhuBiaoRep,  SqlSugarRepository<TraFaXueMingXi> traShenQingFaXueMingXiRep,
        SqlSugarRepository<InvKuCun> invKuCunRep, SqlSugarRepository<TraShenQingJianYan> traShenQingJianYanRep)
    {
        _billNoManager = billNoManager;
        _traShenQingRep = traShenQingRep;
        _taShenQingHuanZheRep = taShenQingHuanZheRep;
        _traShenQingYongXueRep = traShenQingYongXueRep;
        _traShenQingFuHeRep = traShenQingFuHeRep;
        _traShenQingPeiXueZhuBiaoRep = traShenQingPeiXueZhuBiaoRep;
        _traShenQingPeiXueZiBiaoRep = traShenQingPeiXueZiBiaoRep;
        _traShenQingFaXueZhuBiaoRep = traShenQingFaXueZhuBiaoRep;
        _traShenQingFaXueMingXiRep = traShenQingFaXueMingXiRep;
        _invKuCunRep = invKuCunRep;
        _traShenQingJianYanRep = traShenQingJianYanRep;
    }


    [UnitOfWork]
    public async Task<string> AddKuaiSuFaXue(TraKuaiSuFaXueAddInput input)
    {
        input.traShenQingInput.Id = _billNoManager.CreateBillNo("TraShenQing");
        input.traShenQingInput.danJuZhuangTai = DanJuZhuangTai.已生效;
        input.traShenQingInput.danJuLeiXing = "输血申请";
        input.traShenQingYongXueInput.yongXueLeiXing = "快速发血";

        input.traFuHeInput.Id = input.traShenQingInput.Id;
        input.traShenQingHuanZheInput.Id = input.traShenQingInput.Id;
        input.traShenQingYongXueInput.Id = input.traShenQingInput.Id;
        //申请主表
        _traShenQingRep.InsertReturnEntity(input.traShenQingInput.Adapt<TraShenQing>());
        //申请患者表
        _taShenQingHuanZheRep.InsertReturnEntity(input.traShenQingHuanZheInput.Adapt<TraShenQingHuanZhe>());

        SaveJianYan(input.traShenQingJianYanList, input.traShenQingInput.Id);

        //申请用血申请表
        _traShenQingYongXueRep.InsertReturnEntity(input.traShenQingYongXueInput.Adapt<TraShenQingYongXue>());
        //申请复核表
        _traShenQingFuHeRep.InsertReturnEntity(input.traFuHeInput.Adapt<TraFuHe>());
        //配血表保存
        var peiXueMingXiList = await SavePeiXue(input);
        //保存发血信息
        await SaveFaXue(input, peiXueMingXiList);

        // 血液发血
        var xueYeIdList = input.traKuaiSuFaXueMingXiList.Select(t => t.invKuCun.Id).ToList();
        var xueYeList = await _invKuCunRep.Queryable.Where(t => xueYeIdList.Contains(t.Id)).ToListAsync();
        var isChuKuList = xueYeList.Where(t => t.kuCunZhuangTai != KuCunZhuangTai.在库).Select(t => t.xianXueMa).ToList();
        if (isChuKuList.Count > 0)
        {
            var str = String.Join(",", isChuKuList);
            throw Oops.Oh("血液" + str + "不在库");
        }

        _invKuCunRep.Update(u => new() { kuCunZhuangTai = KuCunZhuangTai.已发血 }, u => xueYeIdList.Contains(u.Id));
        return input.traShenQingInput.Id;
    }

    private void SaveJianYan(List<TraShenQingJianYanInput> input, string id)
    {


        // 插入明细表
        List<TraShenQingJianYan> listZiBiao = new List<TraShenQingJianYan>();
        foreach (var item in input)
        {

            item.traShenQingId = id;
            listZiBiao.Add(item.Adapt<TraShenQingJianYan>());

        }
        if (listZiBiao.Count() > 0)
        {
            _traShenQingJianYanRep.BulkCopy(listZiBiao);
        }
    }

    /// <summary>
    /// 配血
    /// </summary>
    /// <returns></returns>
    public async Task<List<TraPeiXueMingXi>> SavePeiXue(TraKuaiSuFaXueAddInput input)
    {
        string id = _billNoManager.CreateBillNo("TraShenQingPeiXue");
        var entity = await _traShenQingPeiXueZhuBiaoRep.InsertReturnEntityAsync(new TraPeiXue
        {
            Id = id,
            CreateTime = DateTime.Now,
            danJuLeiXing = "交叉配血",
            danJuZhuangTai = DanJuZhuangTai.已生效,
            peiXingLeiXing = "本院配型",
            peiXueCiShu = 1,
            traShenQingId = input.traShenQingInput.Id,
        });

        // 插入明细表
        List<TraPeiXueMingXi> listZiBiao = new List<TraPeiXueMingXi>();

        foreach (var item in input.traKuaiSuFaXueMingXiList)
        {
            var mingXi = new TraPeiXueMingXi
            {
                Id = YitIdHelper.NextId(),
                xueYeId = item.invKuCun.Id,
                ciCe = item.ciCe,
                zhuCe = item.zhuCe,
                fuHePeiXueFangFa = item.fuHePeiXueFangFa,
                fuHeRenId = item.fuHeRenId,
                peiXueFangFa = item.peiXueFangFa,
                peiXueJieGuo = item.peiXueJieGuo,
                peiXueRiQi = item.peiXueRiQi,
                peiXueRenId = item.peiXueRenId,
                traPeiXueId = entity.Id,

            };
            //listZiBiao.Add();
            var entityMingXi = await _traShenQingPeiXueZiBiaoRep.InsertReturnEntityAsync(mingXi);

            listZiBiao.Add(entityMingXi);
        }
        //if (listZiBiao.Count() > 0)
        //{
        //    _traShenQingPeiXueZiBiaoRep.BulkCopy(listZiBiao);
        //}
        return listZiBiao;

    }
    /// <summary>
    /// 发血
    /// </summary>
    /// <returns></returns>
    public async Task SaveFaXue(TraKuaiSuFaXueAddInput input, List<TraPeiXueMingXi> peiXueMingXiList)
    {

        var entity = await _traShenQingFaXueZhuBiaoRep.InsertReturnEntityAsync(new TraFaXue
        {
            Id = input.traShenQingInput.Id,
            danJuLeiXing = "快速发血",
            danJuZhuangTai = DanJuZhuangTai.已生效,
            //  FaXueRen = input.traShenQingInput.CreateUserId,
            traShenQingId = input.traShenQingInput.Id,
            CreateTime = DateTime.Now,
            shiFouJinJi = false,
            shiFouZhuiJia = false,
            shuXueQianTiWen = input.shuXueQianTiWen,
            quXueRenId = input.quXueRenId,
            quXueRen = input.quXueRen,
            
            remark = input.remark
        });
        // 插入明细表
        List<TraFaXueMingXi> listMingXi = new List<TraFaXueMingXi>();
        foreach (var item in input.traKuaiSuFaXueMingXiList)
        {
            var traPeiXueMingXiId = peiXueMingXiList.Where(x => x.xueYeId == item.invKuCun.Id).Select(a => a.Id).FirstOrDefault();

            listMingXi.Add(new TraFaXueMingXi
            {
                xueYeId = item.invKuCun.Id,
                traFaXueId = entity.Id,
                traPeiXueMingXiId = traPeiXueMingXiId
            });

        }

        if (listMingXi.Count() > 0)
        {
            await _traShenQingFaXueMingXiRep.InsertRangeAsync(listMingXi);
        }

    }

    /// <summary>
    /// 获取列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<SqlSugarPagedList<TraFaXueOutput>> Page(BaseKeywordPageInput input)
    {

        var traFaXueOutputList = await _traShenQingFaXueZhuBiaoRep.Queryable.FuzzyQuery(input.Keyword, new List<string> { "Id" })
                                .Where(t => t.danJuLeiXing == "快速发血")
                                //.InnerJoin<TraShenQingYongXue>((traFaXue, traShenQingYongXue) => traFaXue.Id == traShenQingYongXue.Id)
                                //.Where((traFaXue, traShenQingYongXue) => traShenQingYongXue.yongXueLeiXing == "快速发血")
                                .Select<TraFaXueOutput>()
                                .OrderByDescending(traFaxue => traFaxue.Id)
                                .ToPagedListAsync(input.Page, input.PageSize);

        return traFaXueOutputList;
    }

    /// <summary>
    /// 得到发血列表详细信息
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public async Task<TraKuaiSuFaXueOutput> GetKuaiSuFaXueMessage(string id)
    {
        var faXueZhuBiao = await _traShenQingFaXueZhuBiaoRep.AsQueryable().FirstAsync(t => t.Id == id);
        //申请主表
        var shenQing = await _traShenQingRep.AsQueryable().FirstAsync(t => t.Id == id);
        //申请患者表
        var huanZhe = await _taShenQingHuanZheRep.AsQueryable().FirstAsync(t => t.Id == id);
        //申请用血申请表
        var yongXue = await _traShenQingYongXueRep.AsQueryable().FirstAsync(t => t.Id == id);
        //申请复核表
       var shenQingFuHe= await _traShenQingFuHeRep.AsQueryable().FirstAsync(t => t.Id == id);
        //发血信息
      var traKuaiSuFaXueMingXiList =await _traShenQingFaXueMingXiRep.AsQueryable().InnerJoin<TraFaXue>((faXueMingXi, faXue) => faXueMingXi.traFaXueId == faXue.Id).Where((faXueMingXi, faXue) => faXue.Id == id)
          .InnerJoin<InvKuCun>((faXueMingXi, faXue, invKuCun) => faXueMingXi.xueYeId == invKuCun.Id)
          .InnerJoin<TraPeiXueMingXi>((faXueMingXi, faXue, invKuCun, peiXueZiBiao) => faXueMingXi.traPeiXueMingXiId == peiXueZiBiao.Id)
          .Select((faXueMingXi, faXue, invKuCun, peiXueZiBiao) => new 
          {
              xueYeId = invKuCun.Id,
              zhuCe = peiXueZiBiao.zhuCe,
              ciCe = peiXueZiBiao.ciCe,
              peiXueJieGuo = peiXueZiBiao.peiXueJieGuo,
              peiXueRenId = peiXueZiBiao.peiXueRenId,
              fuHeRenId = peiXueZiBiao.fuHeRenId,
              peiXueRiQi = peiXueZiBiao.peiXueRiQi,
              peiXueFangFa = peiXueZiBiao.peiXueFangFa,
              fuHePeiXueFangFa = peiXueZiBiao.fuHePeiXueFangFa,
              invKuCun = invKuCun,
          }).ToListAsync();

        var result = traKuaiSuFaXueMingXiList.Select(x => new TraKuaiSuFaXueMingXiInput
        {
            xueYeId = x.xueYeId,
            zhuCe = x.zhuCe,
            ciCe = x.ciCe,
            peiXueJieGuo = x.peiXueJieGuo,
            peiXueRenId = x.peiXueRenId,
            fuHeRenId = x.fuHeRenId,
            peiXueRiQi = x.peiXueRiQi,
            peiXueFangFa = x.peiXueFangFa,
            fuHePeiXueFangFa = x.fuHePeiXueFangFa,
            invKuCun = x.invKuCun.Adapt<InvKuCunInput>()
        }).ToList();
        //输血检验信息

        var traShenQingJianYanList =await _traShenQingJianYanRep.AsQueryable().Where(a=>a.traShenQingId==id).ToListAsync();





        return new TraKuaiSuFaXueOutput
        {
            faXue = faXueZhuBiao.Adapt<TraFaXueOutput>(),
            shenQing = shenQing.Adapt<TraShenQingOutput>(),
            huanZhe = huanZhe.Adapt<TraShenQingHuanZheOutput>(),
            yongXue = yongXue.Adapt<TraShenQingYongXueOutput>(),
            shenQingFuHe = shenQingFuHe.Adapt<TraFuHeOutput>(),
            traKuaiSuFaXueMingXiList = result,
            traShenQingJianYanList= traShenQingJianYanList.Adapt<List<TraShenQingJianYan>>(),
        };

    }


    public async Task Audit(TraKuaiSuFaXueAuditInput input)
    {
        //申请 复核 配血 发血 主表
        _traShenQingRep.Update(u => new() { danJuZhuangTai = DanJuZhuangTai.已生效 }, u => u.Id == input.Id);
        _traShenQingFuHeRep.Update(u => new() { danJuZhuangTai = DanJuZhuangTai.已生效 }, u => u.Id == input.Id);
        _traShenQingPeiXueZhuBiaoRep.Update(u => new() { danJuZhuangTai = DanJuZhuangTai.已生效 }, u => u.traShenQingId == input.Id);
        _traShenQingFaXueZhuBiaoRep.Update(u => new() { danJuZhuangTai = DanJuZhuangTai.已生效, quXueRenId = input.quXueRenId }, u => u.Id == input.Id);

        var xueYeList = await _invKuCunRep.Queryable
            .InnerJoin<TraFaXueMingXi>((kuCun, traFaXueMingXi) => kuCun.Id == traFaXueMingXi.xueYeId)
            .Where((kuCun, traFaXueMingXi) => traFaXueMingXi.traFaXueId == input.Id).ToListAsync();
        var isChuKuList = xueYeList.Where(t => t.kuCunZhuangTai != KuCunZhuangTai.在库).Select(t => t.xianXueMa).ToList();
        if (isChuKuList.Count > 0)
        {
            var str = String.Join(",", isChuKuList);
            throw Oops.Oh("血液" + str + "不在库");
        }
        //血液出库
        var xueYeIdList = xueYeList.Select(t => t.Id).ToList();


        _invKuCunRep.Update(u => new() { kuCunZhuangTai = KuCunZhuangTai.已发血 }, u =>  xueYeIdList.Contains(u.Id));

    }
    [UnitOfWork]
    [HttpPost]
    public async Task UpdateFaXueMingXi(TraKuaiSuFaXueMingXiUpdateInput input)
    {
        // 修改配血明细
        await _traShenQingPeiXueZiBiaoRep.DeleteAsync(t => t.traPeiXueId == input.Id);
        _traShenQingPeiXueZhuBiaoRep.AsUpdateable(new TraPeiXue() { Id = input.Id }).UpdateColumns(it => new { it.UpdateTime, it.UpdateUserId, it.UpdateUserName }).ExecuteCommand();

        // 插入配血明细表
        List<TraPeiXueMingXi> peiXueMingXiList = new List<TraPeiXueMingXi>();

        foreach (var item in input.traKuaiSuFaXueMingXiList)
        {
            var mingXi = new TraPeiXueMingXi
            {
                Id = YitIdHelper.NextId(),
                xueYeId = item.invKuCun.Id,
                ciCe = item.ciCe,
                zhuCe = item.zhuCe,
                fuHePeiXueFangFa = item.fuHePeiXueFangFa,
                fuHeRenId = item.fuHeRenId,
                peiXueFangFa = item.peiXueFangFa,
                peiXueJieGuo = item.peiXueJieGuo,
                peiXueRiQi = item.peiXueRiQi,
                peiXueRenId = item.peiXueRenId,
                traPeiXueId = input.Id,

            };

            peiXueMingXiList.Add(mingXi);
        }
        if (peiXueMingXiList.Count > 0)
        {
            await _traShenQingPeiXueZiBiaoRep.InsertRangeAsync(peiXueMingXiList);
        }
        // 修改发血明细
        await _traShenQingFaXueMingXiRep.DeleteAsync(t => t.traFaXueId == input.Id);
        _traShenQingFaXueZhuBiaoRep.AsUpdateable(new TraFaXue() { Id = input.Id }).UpdateColumns(it => new { it.UpdateTime, it.UpdateUserId, it.UpdateUserName }).ExecuteCommand();

        // 插入发血明细表
        List<TraFaXueMingXi> faXueMingXiList = new List<TraFaXueMingXi>();
        foreach (var item in input.traKuaiSuFaXueMingXiList)
        {
            var traPeiXueMingXiId = peiXueMingXiList.Where(x => x.xueYeId == item.invKuCun.Id).Select(a => a.Id).FirstOrDefault();

            faXueMingXiList.Add(new TraFaXueMingXi
            {
                xueYeId = item.invKuCun.Id,
                traFaXueId = input.Id,
                traPeiXueMingXiId = traPeiXueMingXiId
            });

        }

        if (faXueMingXiList.Count() > 0)
        {
            await _traShenQingFaXueMingXiRep.InsertRangeAsync(faXueMingXiList);
        }

    }

}
